package com.wawei.seeds.utils;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import java.io.IOException;
import java.io.Serializable;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.util.concurrent.Executors;

import retrofit.ErrorHandler;
import retrofit.RestAdapter;
import retrofit.RetrofitError;
import retrofit.client.Request;
import retrofit.client.Response;
import retrofit.client.UrlConnectionClient;

/**
 * Created by parker on 15/1/1.
 */
abstract public class RetrofitNetworkService {
    private static final String TAG = "RetrofitNetworkService";
    public static final String API_ENDPOINT = "http://120.24.96.109";
    public static final int SUCCESS = 200;
    public static final int FAILED = 500;
    public static final String RESULT_SIZE = "result_size";
    public static final int RESULT_ERROR_COUNT = -1;
    public static final String RESULT_ERROR_NONE = "none";
    public static final String RESULT_ERROR = "result_error";
    public static final String RESULT_DATA = "result_data";


    static public final class TimeoutUrlConnectionClient extends UrlConnectionClient {
        @Override
        protected HttpURLConnection openConnection(Request request) throws IOException {
            HttpURLConnection connection = super.openConnection(request);
            connection.setConnectTimeout(15 * 1000);
            connection.setReadTimeout(120 * 1000);
            return connection;
        }
    }

    static public final class RetrofitErrorHandler implements ErrorHandler {
        @Override
        public Throwable handleError(RetrofitError retrofitError) {
            if(retrofitError.getKind() == RetrofitError.Kind.NETWORK){
                if(retrofitError.getCause() instanceof SocketTimeoutException){
                    Log.e(TAG, "Connection Timeout. Please verify your internet connection.");
                    //return new SocketTimeoutException("Connection Timeout. Please verify your internet connection.");
                }
                Response response = retrofitError.getResponse();
                if(null != response && response.getStatus() >= 500){
                    Log.e(TAG, "The service is unavailable because of server's down.");
                    //return new Exception("The service is unavailable because of server's down.");
                }
                else if(null != response && response.getStatus() == 401){
                    Log.e(TAG, "Invalid credentials. Please verify login info.");
                    //return  new Exception("Invalid credentials. Please verify login info.");
                }
                else{
                    Log.e(TAG, "No Connection. Please verify your internet connection.");
                    //return new Exception("No Connection. Please verify your internet connection.");
                }
            }
            return retrofitError;
        }
    }

    static public void handleError(Handler handler, Integer handlerTag, RetrofitError retrofitError){
        if(null != handler && null != handlerTag) {
            Bundle bundle = new Bundle();
            bundle.putInt(RESULT_SIZE, RESULT_ERROR_COUNT);
            bundle.putString(RESULT_ERROR, null == retrofitError?"Something wrong":retrofitError.getMessage());

            Message message = handler.obtainMessage();
            message.what = handlerTag.intValue();
            message.setData(bundle);

            handler.sendMessage(message);
        }
    }

    static public void handleSuccess(Handler handler, Integer handlerTag, Serializable serializable){
        if(null != handler && null != handlerTag) {
            Bundle bundle = new Bundle();
            bundle.putSerializable(RESULT_DATA, serializable);
            bundle.putString(RESULT_ERROR, RESULT_ERROR_NONE);

            Message message = handler.obtainMessage();
            message.what = handlerTag.intValue();
            message.setData(bundle);

            handler.sendMessage(message);
        }
    }

    static public RestAdapter makeRestAdapter(){
        RestAdapter restAdapter = new RestAdapter.Builder()
                .setEndpoint(RetrofitNetworkService.API_ENDPOINT)
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .setClient(new RetrofitNetworkService.TimeoutUrlConnectionClient())
                .setErrorHandler(new RetrofitNetworkService.RetrofitErrorHandler())
                .build();
        return restAdapter;
    }

    static public RestAdapter makeAsyncRestAdapter(){
        RestAdapter restAdapter = new RestAdapter.Builder()
                .setEndpoint(RetrofitNetworkService.API_ENDPOINT)
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .setClient(new RetrofitNetworkService.TimeoutUrlConnectionClient())
                .setExecutors(Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()),null)
                .setErrorHandler(new RetrofitNetworkService.RetrofitErrorHandler())
                .build();
        return restAdapter;
    }
}
